package net.sk.china.city.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.SneakyThrows;
import net.sk.china.city.constant.HotActivityOrderKey;
import net.sk.china.city.domain.*;
import net.sk.china.city.domain.dto.PageData;
import net.sk.china.city.domain.dto.WorkHourPageData;
import net.sk.china.city.domain.dto.activity.ActivityInfoDTO;
import net.sk.china.city.domain.dto.activity.ActivitySearchDTO;
import net.sk.china.city.domain.dto.analyse.*;
import net.sk.china.city.domain.dto.team.TeamSearchDTO;
import net.sk.china.city.domain.dto.user.VolunteerPopulationDTO;
import net.sk.china.city.domain.vo.*;
import net.sk.china.city.mapper.*;
import net.sk.china.city.service.IAnalyseService;
import net.sk.china.city.utils.ConvertUtil;
import net.sk.china.city.utils.ServletUtil;
import net.sk.china.city.utils.Tuple2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.Month;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class AnalyseServiceImpl implements IAnalyseService {
    private final UserMapper userMapper;
    private final ArTeamMapper arTeamMapper;
    private final ArActivityMapper arActivityMapper;

    @Autowired
    private ArDonateMapper arDonateMapper;

    @Autowired
    private ArDonateSourceMapper arDonateSourceMapper;

    @Autowired
    private ArDonationsMapper arDonationsMapper;

    @Autowired
    private ArExchangeMapper arExchangeMapper;

    @Autowired
    private ArExchangeItemMapper arExchangeItemMapper;

    @Autowired
    private ArSupermarketProductMapper arSupermarketProductMapper;

    @Autowired
    private ArArticleMapper articleMapper;
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private ArActivityRecordMapper arActivityRecordMapper;

    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private AnalyseMapper analyseMapper;
    @Autowired
    private ArRegionMapper arRegionMapper;

    @Autowired
    private ArHomeProductMapper arHomeProductMapper;

    @Autowired
    private ArOrderMapper arOrderMapper;

    @Autowired
    private ArOrderItemMapper arOrderItemMapper;

    @Autowired
    private ArHomeShopMapper arHomeShopMapper;


    public AnalyseServiceImpl(UserMapper userMapper, ArTeamMapper arTeamMapper, ArActivityMapper arActivityMapper) {
        this.userMapper = userMapper;
        this.arTeamMapper = arTeamMapper;
        this.arActivityMapper = arActivityMapper;
    }

    @Override
    public AnalyseDTO analyseVolunteerData() {
        String platformId = "0,100";
        // 总志愿者数
        Long volunteerCount = userMapper.countVolunteer(platformId);
        Tuple2<Long, Long> integerIntegerTuple2 = countLevel();
        // 社区级服务站数量
        long communitySiteCount = integerIntegerTuple2.getT1();
        // 网格数（网格片区数）
        long cellCount = arRegionMapper.selectRegionCount();

        // 志愿队伍数
        Long teamCount = arTeamMapper.countTeam(platformId);
        // 志愿活动数
        long activityCount = arActivityMapper.countActivity(platformId);
        // 累计工时
        BigDecimal totalWorkHour = userMapper.sumWorkHour(platformId);
        // 平均工时
        BigDecimal avgWorkHour = userMapper.volunteerAvgWorkHour(platformId);
        //慈善企业数
//        Long enterpriseCount = arDonateSourceMapper.selectCount(new QueryWrapper<ArDonateSource>()
//                .eq("source_category", "2")
//                .like("platform_id", "%" + platformId + "%"));
//        //慈善资源价值
//        BigDecimal totalPriceSum = arDonateMapper.selectTotalPriceSum(platformId);
//        //积分兑换次数
//        Long exchangeCount = arExchangeMapper.selectCount(new QueryWrapper<ArExchange>()
////                .eq("exchange_status", "1")
//                .like("platform_id", "%" + platformId + "%"));
        AnalyseDTO analyseDTO = new AnalyseDTO();
        analyseDTO.setVolunteerCount(volunteerCount);
        analyseDTO.setTeamCount(teamCount);
        analyseDTO.setActivityCount(activityCount);
        analyseDTO.setTotalWorkHour(totalWorkHour);
        analyseDTO.setAvgWorkHour(avgWorkHour);
        analyseDTO.setCommunityLevelCount(communitySiteCount);
        analyseDTO.setGridLevelCount(cellCount);
//        analyseDTO.setEnterpriseCount(enterpriseCount);
//        analyseDTO.setTotalPriceSum(totalPriceSum);
//        analyseDTO.setExchangeCount(exchangeCount);
        return analyseDTO;
    }


    private Tuple2<Long, Long> countLevel() {
        String platformId = "0,100";
        List<SysDept> sysDeptList = sysDeptMapper.selectDeptListByPlatformId(platformId);
        long communityLevelCount = 0;
        long gridLevelCount = 0;
        for (SysDept sysDept : sysDeptList) {
            String ancestors = sysDept.getAncestors();
            String[] ancestorArray = ancestors.split(",");
            // 社区级
            if (ancestorArray.length == 4) {
                ++communityLevelCount;
            }
            // 片区级
            if (ancestorArray.length == 5) {
                ++gridLevelCount;
            }
        }
        return Tuple2.of(communityLevelCount, gridLevelCount);
    }

    /**
     * 捐赠排行榜
     */
    @Override
    public List<DonationRankVO> donationRank() {
        String platformId = "0," + ServletUtil.getSiteId();
        ArDonateSource arDonateSource = new ArDonateSource();
        arDonateSource.setPlatformId(platformId);
        return arDonateMapper.donationRank(arDonateSource);
    }

    /**
     * 慈善超市销量前五的商品
     *
     * @return
     */
    @Override
    public List<ArSupermarketProduct> SupermarketRank() {
        String platformId = "0," + ServletUtil.getSiteId();
        return arSupermarketProductMapper.SupermarketRank(platformId);
    }


    /**
     * 报道占比
     *
     * @return
     */
    @Override
    public List<ReportProportionVO> ReportProportion() {
        String platformId = "0," + ServletUtil.getSiteId();
        return articleMapper.ReportProportion(platformId);
    }

    @Override
    public List<ActivityRankDTO> analyseHotActivity(HotActivityOrderKey key) {
        String orderKey = key.getKey();
        return arActivityRecordMapper.selectTop5Activity(orderKey);
    }

    @Override
    public List<VolunteerCountRankDTO> analyseSiteVolunteerTop5(VolunteerCountRankSearchDTO volunteerCountRankSearchDTO) {
        Integer mode = volunteerCountRankSearchDTO.getMode();
        Integer current = volunteerCountRankSearchDTO.getCurrent();
        Integer size = volunteerCountRankSearchDTO.getSize();
        if (mode == 0) {
            // 前十
            PageHelper.startPage(1, 10);
            List<VolunteerCountRankDTO> volunteerCountRankDTOS = userMapper.analyseSiteVolunteerTop10(null, null);
            computeDiff(volunteerCountRankDTOS);
            return volunteerCountRankDTOS;
        }
        PageHelper.startPage(current, size);
        List<VolunteerCountRankDTO> volunteerCountRankDTOS = userMapper.analyseSiteVolunteerTop10(null, null);
        computeDiff(volunteerCountRankDTOS);
        return volunteerCountRankDTOS;
    }

    private void computeDiff(List<VolunteerCountRankDTO> volunteerCountRankDTOS) {
        LocalDate today = LocalDate.now();
        LocalDate thisMonthStartDay = today.withDayOfMonth(1);
        LocalDate lastMonthStartDay = thisMonthStartDay.minusMonths(1);
        LocalDate nextMonthStartDay = thisMonthStartDay.plusMonths(1);
        Map<Long, Long> lastMonthData = userMapper.analyseSiteVolunteerTop10(lastMonthStartDay, thisMonthStartDay)
                .stream()
                .collect(Collectors.toMap(VolunteerCountRankDTO::getDeptId,
                        VolunteerCountRankDTO::getVolunteerCount));
        Map<Long, Long> lastAndThisMonthData = userMapper.analyseSiteVolunteerTop10(lastMonthStartDay, nextMonthStartDay)
                .stream()
                .collect(Collectors.toMap(VolunteerCountRankDTO::getDeptId,
                        VolunteerCountRankDTO::getVolunteerCount));
        for (VolunteerCountRankDTO volunteerCountRankDTO : volunteerCountRankDTOS) {
            Long deptId = volunteerCountRankDTO.getDeptId();
            Long diff = lastAndThisMonthData.get(deptId) - lastMonthData.get(deptId);
            volunteerCountRankDTO.setDiffCount(diff);
        }
    }

    @Override
    public List<SitePin> siteList() {
//        PlatformIdHolder.getPlatformId();
//        String platformId = "0,100";
//        List<SysDept> sysDeptList = sysDeptMapper.selectDeptListByPlatformId(platformId);
//        ArrayList<SitePin> sitePinList = new ArrayList<>();
//        for (SysDept sysDept : sysDeptList) {
//            String ancestors = sysDept.getAncestors();
//            String[] ancestorArray = ancestors.split(",");
//            // 社区级
//            if (ancestorArray.length == 4) {
//
//                sitePinList.add(sitePin);
//            }
//        }
        List<Site> siteList = sysDeptMapper.selectAllSite();
        Map<Long, Long> deptIdPersonCountMap = sysDeptMapper.countVolunteerUnderSysDept()
                .stream()
                .collect(Collectors.toMap(DeptVolunteerCountPair::getDeptId, DeptVolunteerCountPair::getPersonCount));
        return ConvertUtil.converList(siteList, site -> {
            SitePin sitePin = new SitePin();
            sitePin.setSiteId(site.getId());
            sitePin.setSiteName(site.getName());
            sitePin.setLongitude(site.getLongitude());
            sitePin.setLatitude(site.getLatitude());
            sitePin.setIcon("");
            sitePin.setPersonCount(deptIdPersonCountMap.get(site.getId()));
            return sitePin;
        });
    }

    @Override
    public List<GridIdNamePair> gridPair(Long communityId) {
        List<SysDept> gridCellList = sysDeptMapper.selectDirectChildrenByParentId(communityId);
        ArrayList<GridIdNamePair> gridIdNamePairs = new ArrayList<>();
        for (SysDept sysDept : gridCellList) {
            GridIdNamePair gridIdNamePair = new GridIdNamePair(sysDept.getDeptId(), sysDept.getDeptName());
            gridIdNamePairs.add(gridIdNamePair);
        }
        return gridIdNamePairs;
    }

    @Override
    public GridAnalysis gridAnalysis(Long gridId) {
        GridVolunteerAnalysis gridVolunteerAnalysis = userMapper.analyseGridVolunteerData(gridId);
        Long takePartActivityCount = userMapper.analyseGridActivityCount(gridId);
        // todo 加入了多个队伍的志愿者兑换，会出现兑换次数重复
        Long totalExchange = arExchangeMapper.selectTotalExchange(gridId);

        GridAnalysis gridAnalysis = new GridAnalysis();
        gridAnalysis.setGridId(gridId);
        gridAnalysis.setTotalVolunteer(gridVolunteerAnalysis.getVolunteerCount());
        gridAnalysis.setTotalWorkHour(gridVolunteerAnalysis.getTotalWorkHour());
        gridAnalysis.setTotalActivity(takePartActivityCount);
        gridAnalysis.setTotalExchange(totalExchange);
        return gridAnalysis;
    }

    @Override
    public PageData<GridVolunteerItem> gridVolunteerPage(GridVolunteerPageSearchDTO gridVolunteerPageSearchDTO) {
//        Long gridId = gridVolunteerPageSearchDTO.getGridId();
        Integer current = gridVolunteerPageSearchDTO.getCurrent();
        Integer size = gridVolunteerPageSearchDTO.getSize();
        PageHelper.startPage(current, size);
        Page<GridVolunteerItem> gridVolunteerPage = userMapper.getGridVolunteerPage();
        for (GridVolunteerItem gridVolunteerItem : gridVolunteerPage) {
            Long count = arExchangeMapper.selectCount(new QueryWrapper<ArExchange>().eq("user_id", gridVolunteerItem.getUserId()));
            gridVolunteerItem.setExchangeCount(count.intValue());
        }
        return new PageData<>(gridVolunteerPage.getPageNum(), gridVolunteerPage.getPageSize(), gridVolunteerPage.getTotal(), gridVolunteerPage.getResult());
    }

    @Override
    public int generateClosure() {
        List<SysDept> sysDeptList = sysDeptMapper.selectAllDept();
        for (SysDept sysDept : sysDeptList) {
            Long deptId = sysDept.getDeptId();
            Long parentId = sysDept.getParentId();
            if (parentId == 0) {
                // 根节点
                jdbcTemplate.update("insert into sys_dept_relation(ancestor_id, descendant_id, distance) values (?, ?, ?)", deptId, deptId, 0);
                continue;
            }
            String ancestors = sysDept.getAncestors();
            String[] ancestorIdArray = ancestors.split(",");
            String[] newArray = new String[ancestorIdArray.length - 1];
            System.arraycopy(ancestorIdArray, 1, newArray, 0, ancestorIdArray.length - 1);
            jdbcTemplate.update("insert into sys_dept_relation(ancestor_id, descendant_id, distance) values (?, ?, ?)", deptId, deptId, 0);
            int distance = 0;
            int currentIndex = newArray.length - 1;
            for (int i = currentIndex; i >= 0; i--) {
                String currentAncestor = newArray[i];
                distance = distance + 1;
                jdbcTemplate.update("insert into sys_dept_relation(ancestor_id, descendant_id, distance) values (?, ?, ?)", currentAncestor, deptId, distance);
            }
        }
        return 1;
    }

    @Override
    public List<RegionPoint> thisRegionLeveList(Long parentRegionId) {
        return analyseMapper.selectThisRegionLevelList(parentRegionId);
    }

    @Override
    public List<RegionPoint> gridLeveList(Long townRegionId) {
        return analyseMapper.selectGridLevelList(townRegionId);
    }

    @Override
    public List<RegionPoint> countyLevelCellList(Long countyId) {
        return analyseMapper.selectCountyLevelCellList(countyId);
    }

    @Transactional
    @Override
    public void mergeLeafNode() {
        List<Map<String, Object>> stringStringMap = sysDeptMapper.selectLeafNode();
//        // 先更新队伍
//        for (Map<String, Object> stringMap : stringStringMap) {
//            Object oldSiteId = stringMap.get("dept_id");
//            Object newSiteId = stringMap.get("parent_id");
//            Object newPlatformId = stringMap.get("ancestors");
//            arTeamMapper.updateTeamSite(oldSiteId, newSiteId, newPlatformId);
//        }
//        // 再更新用户-队伍的关联（申请）
//        List<ArTeam> allTeamList = arTeamMapper.selectAllTeam();
//        for (ArTeam arTeam : allTeamList) {
//            arTeamMapper.updateUserTeamPlatformId(arTeam.getPkId(), arTeam.getPlatformId());
//        }
        // 删除掉叶节点
        for (Map<String, Object> stringObjectMap : stringStringMap) {
            Object lefNodeId = stringObjectMap.get("dept_id");
            sysDeptMapper.realDeleteDeptById(lefNodeId);
        }
    }

    /**
     * 志愿者人员分布
     *
     * @return
     */
    // todo 重新调整接口，完善月份填充逻辑
    @Override
    public List<VolunteerPopulationVO> volunteerPopulation() {
        String platformId = "0," + ServletUtil.getSiteId();
        List<VolunteerPopulationDTO> volunteerPopulationDTOS = userMapper.volunteerPopulation(platformId);

        // 使用Map来根据月份分组，并初始化好容器
        Month thisMonth = LocalDate.now().getMonth();
        Map<String, List<VolunteerPopulationDTO>> monthMap = new HashMap<>();
        for (int i = 0; i < 6; i++) {
            Integer currentMon = thisMonth.minus(i).getValue();
            monthMap.put(currentMon.toString(), new ArrayList<>());
        }
        // 把数据库来源数据根据月份分类
        for (VolunteerPopulationDTO dto : volunteerPopulationDTOS) {
            String month = dto.getMonth();
            Integer currentMonth = Integer.valueOf(month);
            String currentMonStr = currentMonth.toString();
            if (monthMap.containsKey(currentMonStr)) {
                monthMap.get(currentMonStr).add(dto);
            } else {
                List<VolunteerPopulationDTO> list = new ArrayList<>();
                list.add(dto);
                monthMap.put(currentMonStr, list);
            }
        }

        // 遍历Map，计算政治面貌的数量
        List<VolunteerPopulationVO> volunteerPopulationVOS = new ArrayList<>();
        for (Map.Entry<String, List<VolunteerPopulationDTO>> entry : monthMap.entrySet()) {
            String currentMonth = entry.getKey();
            List<VolunteerPopulationDTO> currentMonthData = entry.getValue();
            // 组装返回数据体
            VolunteerPopulationVO populationVO = new VolunteerPopulationVO();
            populationVO.setMonth(currentMonth);
            // 目前对月数据进行循环，这里将每个月的数据进行政治面貌分类统计
            List<VolunteerPopulationDTO> newPopulationDTOList = getVolunteerPopulationDTOList(currentMonthData);
            populationVO.setVolunteerPopulationDTOS(newPopulationDTOList);
            volunteerPopulationVOS.add(populationVO);
        }
        // 返回volunteerPopulationVOS数组
        return volunteerPopulationVOS;
    }

    private List<VolunteerPopulationDTO> getVolunteerPopulationDTOList(List<VolunteerPopulationDTO> currentMonthDataList) {
        List<VolunteerPopulationDTO> newPopulationDTOList = new ArrayList<>();
        // 政治面貌有多少项，这里就进行多少次的循环
        for (int i = 0; i <= 4; i++) {
            boolean found = false;
            for (VolunteerPopulationDTO currentMonthDataItem : currentMonthDataList) {
                if (currentMonthDataItem.getPoliticalIdentityId() == i) {
                    newPopulationDTOList.add(currentMonthDataItem);
                    found = true;
                    break;
                }
            }
            if (!found) {
                VolunteerPopulationDTO emptyDTO = new VolunteerPopulationDTO();
                emptyDTO.setPoliticalIdentityId(i);
                emptyDTO.setVolunteerCount(0L);
                newPopulationDTOList.add(emptyDTO);
            }
        }
        return newPopulationDTOList;
    }

    public static void main(String[] args) {
        List<String> list = Arrays.asList("05", "08", "01", "06");
        Integer minMonth = list.stream()
                .map(volunteerPopulationDTO -> Integer.valueOf(volunteerPopulationDTO))
                .min(Comparator.comparing(x -> x))
                .orElse(null);
        System.out.println(minMonth);
    }


    /**
     * 获取慈善超市首页基础信息
     *
     * @return
     */
    @Override
    public SupermarketHomeVO getSupermarketHome() {
        SupermarketHomeVO supermarketHomeVO = new SupermarketHomeVO();
        supermarketHomeVO.setExchangeTotalValue(arExchangeMapper.selectExchangeTotalValue());
        supermarketHomeVO.setProductTotalNum(arSupermarketProductMapper.selectTotalProductNum());
        supermarketHomeVO.setProductTotalExchangeNum(arExchangeItemMapper.selectProductTotalExchangeNum());
        supermarketHomeVO.setProductTotalValue(arSupermarketProductMapper.selectTotalProductValue());
        supermarketHomeVO.setCorpNum(arDonateSourceMapper.selectCorpNum());

        //周内
        Date date = new Date();
        DateTime beginOfWeek = DateUtil.beginOfWeek(date);
        DateTime endOfBeginOfWeek = DateUtil.endOfDay(beginOfWeek);
        DateTime endOfWeek = DateUtil.endOfWeek(date);
        List<Integer> weekExchangeNum = new ArrayList<>(7);
        for (int i = 0; i < 7; i++) {
            int dayNum = 0;
            List<ArExchange> exchanges = arExchangeMapper.selectList(new QueryWrapper<ArExchange>().between("create_time", DateUtil.offsetDay(beginOfWeek, i), DateUtil.offsetDay(endOfBeginOfWeek, i)));
            if (exchanges != null) {
                ArExchangeItem arExchangeItem = new ArExchangeItem();
                for (ArExchange exchange : exchanges) {
                    arExchangeItem.setExchangeId(exchange.getId());
                    List<ArExchangeItem> arExchangeItems = arExchangeItemMapper.selectArExchangeItemList(arExchangeItem);
                    for (ArExchangeItem exchangeItem : arExchangeItems) {
                        dayNum += exchangeItem.getProductNumber();
                    }
                }
            }
            weekExchangeNum.add(dayNum);
        }
        supermarketHomeVO.setWeekExchangeNum(weekExchangeNum);

        //月内
        DateTime beginOfMonth = DateUtil.beginOfMonth(date);
        DateTime endOfBeginOfMonth = DateUtil.endOfDay(beginOfMonth);
        DateTime endOfMonth = DateUtil.endOfMonth(date);
        long monthDay = DateUtil.between(beginOfMonth, endOfMonth, DateUnit.DAY) + 1;
        List<Integer> monthExchangeNum = new ArrayList<>();
        for (int i = 0; i < monthDay; i++) {
            int monthDayNum = 0;
            List<ArExchange> monthExchanges = arExchangeMapper.selectList(new QueryWrapper<ArExchange>().between("create_time", DateUtil.offsetDay(beginOfMonth, i), DateUtil.offsetDay(endOfBeginOfMonth, i)));
            if (monthExchanges != null) {
                ArExchangeItem arExchangeItem = new ArExchangeItem();
                for (ArExchange exchange : monthExchanges) {
                    arExchangeItem.setExchangeId(exchange.getId());
                    List<ArExchangeItem> arExchangeItems = arExchangeItemMapper.selectArExchangeItemList(arExchangeItem);
                    for (ArExchangeItem exchangeItem : arExchangeItems) {
                        monthDayNum += exchangeItem.getProductNumber();
                    }
                }
            }
            monthExchangeNum.add(monthDayNum);
        }
        supermarketHomeVO.setMonthExchangeNum(monthExchangeNum);

        //今日兑换单数
        int todayExchangeOrderNum = 0;
        DateTime beginOfDay = DateUtil.beginOfDay(date);
        DateTime endOfDay = DateUtil.endOfDay(date);
        List<ArExchange> todayExchanges = arExchangeMapper.selectList(new QueryWrapper<ArExchange>().between("create_time", beginOfDay, endOfDay));
        if (todayExchanges != null) {
//            ArExchangeItem arExchangeItem = new ArExchangeItem();
//            for (ArExchange todayExchange : todayExchanges) {
//                arExchangeItem.setExchangeId(todayExchange.getId());
//                List<ArExchangeItem> arExchangeItems = arExchangeItemMapper.selectArExchangeItemList(arExchangeItem);
//                for (ArExchangeItem exchangeItem : arExchangeItems) {
//                    todayExchangeNum += exchangeItem.getProductNumber();
//                }
//            }
            todayExchangeOrderNum = todayExchanges.size();
        }
        supermarketHomeVO.setTodayExchangeOrderNum(todayExchangeOrderNum);

        //昨日兑换单数
        int yesterdayExchangeOrderNum = 0;
        DateTime yesterday = DateUtil.yesterday();
        DateTime beginOfYesterday = DateUtil.beginOfDay(yesterday);
        DateTime endOfYesterday = DateUtil.endOfDay(yesterday);
        List<ArExchange> yesterdayExchanges = arExchangeMapper.selectList(new QueryWrapper<ArExchange>().between("create_time", beginOfYesterday, endOfYesterday));
        if (yesterdayExchanges != null) {
//            ArExchangeItem arExchangeItem = new ArExchangeItem();
//            for (ArExchange exchange : yesterdayExchanges) {
//                arExchangeItem.setExchangeId(exchange.getId());
//                List<ArExchangeItem> arExchangeItems = arExchangeItemMapper.selectArExchangeItemList(arExchangeItem);
//                for (ArExchangeItem exchangeItem : arExchangeItems) {
//                    yesterdayExchangeNum += exchangeItem.getProductNumber();
//                }
//            }
            yesterdayExchangeOrderNum = yesterdayExchanges.size();
        }
        supermarketHomeVO.setCompareWithYesterdayExchangeOrderNum(todayExchangeOrderNum - yesterdayExchangeOrderNum);

        //本周兑换单数
        int weekExchangeOrderNum = 0;
        List<ArExchange> weekExchanges = arExchangeMapper.selectList(new QueryWrapper<ArExchange>().between("create_time", beginOfWeek, endOfWeek));
        if (weekExchanges != null) {
            weekExchangeOrderNum = weekExchanges.size();
        }
        supermarketHomeVO.setWeekExchangeOrderNum(weekExchangeOrderNum);

        //上周兑换单数
        int lastWeekExchangeOrderNum = 0;
        DateTime lastWeek = DateUtil.lastWeek();
        DateTime beginOfLastWeek = DateUtil.beginOfWeek(lastWeek);
        DateTime endOfLastWeek = DateUtil.endOfWeek(lastWeek);
        List<ArExchange> lastWeekExchanges = arExchangeMapper.selectList(new QueryWrapper<ArExchange>().between("create_time", beginOfLastWeek, endOfLastWeek));
        if (lastWeekExchanges != null) {
//            ArExchangeItem arExchangeItem = new ArExchangeItem();
//            for (ArExchange lastWeekExchange : lastWeekExchanges) {
//                arExchangeItem.setExchangeId(lastWeekExchange.getId());
//                List<ArExchangeItem> arExchangeItems = arExchangeItemMapper.selectArExchangeItemList(arExchangeItem);
//                for (ArExchangeItem exchangeItem : arExchangeItems) {
//                    lastWeekExchangeNum += exchangeItem.getProductNumber();
//                }
//            }
            lastWeekExchangeOrderNum = lastWeekExchanges.size();
        }
        supermarketHomeVO.setCompareWithLastWeekExchangeOrderNum(weekExchangeOrderNum - lastWeekExchangeOrderNum);

        //本月兑换单数
        int monthExchangeOrderNum = 0;
        List<ArExchange> monthExchanges = arExchangeMapper.selectList(new QueryWrapper<ArExchange>().between("create_time", beginOfMonth, endOfMonth));
        if (monthExchanges != null) {
            monthExchangeOrderNum = monthExchanges.size();
        }
        supermarketHomeVO.setMonthExchangeOrderNum(monthExchangeOrderNum);

        //上月兑换单数
        int lastMonthExchangeOrderNum = 0;
        DateTime lastMonth = DateUtil.lastMonth();
        DateTime beginOfLastMonth = DateUtil.beginOfMonth(lastMonth);
        DateTime endOfLastMonth = DateUtil.endOfMonth(lastMonth);
        List<ArExchange> lastMonthExchanges = arExchangeMapper.selectList(new QueryWrapper<ArExchange>().between("create_time", beginOfLastMonth, endOfLastMonth));
        if (lastMonthExchanges != null) {
//            ArExchangeItem arExchangeItem = new ArExchangeItem();
//            for (ArExchange lastMonthExchange : lastMonthExchanges) {
//                arExchangeItem.setExchangeId(lastMonthExchange.getId());
//                List<ArExchangeItem> arExchangeItems = arExchangeItemMapper.selectArExchangeItemList(arExchangeItem);
//                for (ArExchangeItem exchangeItem : arExchangeItems) {
//                    lastMonthExchangeNum += exchangeItem.getProductNumber();
//                }
//            }
            lastMonthExchangeOrderNum = lastMonthExchanges.size();
        }
        supermarketHomeVO.setCompareWithLastMonthExchangeOrderNum(monthExchangeOrderNum - lastMonthExchangeOrderNum);

        return supermarketHomeVO;
    }

    /**
     * 获取热门兑换商品
     *
     * @return
     */
    @Override
    public List<SupermarketProductVO> getHotExchangeProductList() {
        return arSupermarketProductMapper.selectHotExchangeProductList();
    }

    /**
     * 获取最新兑换订单
     *
     * @return
     */
    @Override
    public List<ArExchangeVO> getLastExchange() {
        return arExchangeMapper.getLastExchange();
    }

    /**
     * 获取捐赠来源占比
     *
     * @return
     */
    @SneakyThrows
    @Override
    public List<Integer> getDonateSourcePercent() {
        List<Integer> percents = new ArrayList<>();
        int personPercent = 0;
        int corpPercent = 0;
        int organizationPercent = 0;
        int governmentPercent = 0;
        List<ArDonate> arDonates = arDonateMapper.selectList(new QueryWrapper<ArDonate>().eq("del_flag", 0));
        for (ArDonate arDonate : arDonates) {
            List<ArDonations> arDonations = arDonationsMapper.selectList(new QueryWrapper<ArDonations>().eq("donate_id", arDonate.getId()));
            int num = 0;
            for (ArDonations arDonation : arDonations) {
                num += arDonation.getItemNumber();
            }
            List<Long> sourceIds = new ObjectMapper().readValue(arDonate.getSourceId(), new TypeReference<List<Long>>() {
            });
            for (Long sourceId : sourceIds) {
                ArDonateSource arDonateSource = arDonateSourceMapper.selectById(sourceId);
                if (arDonateSource.getDelFlag().equals("0")) {
                    switch (arDonateSource.getSourceCategory()) {
                        case "1":
                            personPercent += num;
                            break;
                        case "2":
                            corpPercent += num;
                            break;
                        case "3":
                            organizationPercent += num;
                            break;
                        case "4":
                            governmentPercent += num;
                            break;
                    }
                }
            }
        }
        percents.add(personPercent);
        percents.add(corpPercent);
        percents.add(organizationPercent);
        percents.add(governmentPercent);
        return percents;
    }

    /**
     * 获取义购之家基础数据
     *
     * @return
     */
    @Override
    public HomeInfoVO getHomeInfo() {
        HomeInfoVO homeInfoVO = new HomeInfoVO();
        Integer totalSales = arOrderMapper.selectTotalSales();
        if (totalSales == null)
            totalSales = 0;
        homeInfoVO.setTotalSales(totalSales);

        Date date = new Date();
        //今日总销售额
        DateTime beginOfDay = DateUtil.beginOfDay(date);
        DateTime endOfDay = DateUtil.endOfDay(date);
        Integer todaySales = arOrderMapper.selectTimeBetweenSales(beginOfDay, endOfDay);
        if (todaySales == null)
            todaySales = 0;
        homeInfoVO.setTodaySales(todaySales);

        //本周销售额
        DateTime beginOfWeek = DateUtil.beginOfWeek(date);
        DateTime endOfWeek = DateUtil.endOfWeek(date);
        DateTime endOfBeginOfWeek = DateUtil.endOfDay(beginOfWeek);
        List<Integer> weekSales = new ArrayList<>(7);
        int weekTotalSales = 0;
        for (int i = 0; i < 7; i++) {
            Integer dayNum = arOrderMapper.selectTimeBetweenSales(DateUtil.offsetDay(beginOfWeek, i), DateUtil.offsetDay(endOfBeginOfWeek, i));
            if (dayNum == null)
                dayNum = 0;
            weekTotalSales += dayNum;
            weekSales.add(dayNum);
        }
        homeInfoVO.setWeekSales(weekSales);
        //本周总销售额
        homeInfoVO.setWeekTotalSales(weekTotalSales);

        //本月销售额
        DateTime beginOfMonth = DateUtil.beginOfMonth(date);
        DateTime endOfMonth = DateUtil.endOfMonth(date);
        DateTime endOfBeginOfMonth = DateUtil.endOfDay(beginOfMonth);
        long monthDay = DateUtil.between(beginOfMonth, endOfMonth, DateUnit.DAY) + 1;
        List<Integer> monthSales = new ArrayList<>();
        int monthTotalSales = 0;
        for (int i = 0; i < monthDay; i++) {
            Integer dayNum = arOrderMapper.selectTimeBetweenSales(DateUtil.offsetDay(beginOfMonth, i), DateUtil.offsetDay(endOfBeginOfMonth, i));
            if (dayNum == null)
                dayNum = 0;
            monthTotalSales += dayNum;
            monthSales.add(dayNum);
        }
        homeInfoVO.setMonthSales(monthSales);
        //本月总销售额
        homeInfoVO.setMonthTotalSales(monthTotalSales);

        //今日订单量
        Integer todayOrders = arOrderMapper.selectTimeBetweenOrderNum(beginOfDay, endOfDay);
        if (todayOrders == null)
            todayOrders = 0;
        homeInfoVO.setTodayOrders(todayOrders);

        //对比昨日订单量
        DateTime yesterday = DateUtil.yesterday();
        DateTime beginOfYesterday = DateUtil.beginOfDay(yesterday);
        DateTime endOfYesterday = DateUtil.endOfDay(yesterday);
        Integer yesterdayOrders = arOrderMapper.selectTimeBetweenOrderNum(beginOfYesterday, endOfYesterday);
        if (yesterdayOrders == null)
            yesterdayOrders = 0;
        homeInfoVO.setCompareWithYesterdayOrders(todayOrders - yesterdayOrders);

        //本周订单量
        Integer weekOrders = arOrderMapper.selectTimeBetweenOrderNum(beginOfWeek, endOfWeek);
        if (weekOrders == null)
            weekOrders = 0;
        homeInfoVO.setWeekOrders(weekOrders);

        //对比上周订单量
        DateTime lastWeek = DateUtil.lastWeek();
        DateTime beginOfLastWeek = DateUtil.beginOfWeek(lastWeek);
        DateTime endOfLastWeek = DateUtil.endOfWeek(lastWeek);
        Integer lastWeekOrders = arOrderMapper.selectTimeBetweenOrderNum(beginOfLastWeek, endOfLastWeek);
        if (lastWeekOrders == null)
            lastWeekOrders = 0;
        homeInfoVO.setCompareWithLastWeekOrders(weekOrders - lastWeekOrders);

        //本月订单量
        Integer monthOrders = arOrderMapper.selectTimeBetweenOrderNum(beginOfMonth, endOfMonth);
        if (monthOrders == null) {
            monthOrders = 0;
        }
        homeInfoVO.setMonthOrders(monthOrders);

        //对比上月订单量
        DateTime lastMonth = DateUtil.lastMonth();
        DateTime beginOfLastMonth = DateUtil.beginOfMonth(lastMonth);
        DateTime endOfLastMonth = DateUtil.endOfMonth(lastMonth);
        Integer lastMonthOrders = arOrderMapper.selectTimeBetweenOrderNum(beginOfLastMonth, endOfLastMonth);
        if (lastMonthOrders == null)
            lastMonthOrders = 0;
        homeInfoVO.setCompareWithLastMonthOrders(monthOrders - lastMonthOrders);

        return homeInfoVO;
    }

    /**
     * 获取热门商品排行10条
     *
     * @return
     */
    @Override
    public List<HomeProductInfoVO> popularProductRanking() {
        return arHomeProductMapper.popularProductRanking();
    }


    /**
     * 订单（义购）
     * @return
     */
    @Override
    public List<LatestOrdersVO> latestOrders(String orderStatusList) {
        // todo  数据隔离
        List<ArOrder> arOrders;
        if(orderStatusList.equals("1")){
            arOrders=arOrderMapper.latestOrders();
        }else {
            arOrders=arOrderMapper.refundOrder();
        }
        List<LatestOrdersVO> latestOrdersList = new ArrayList<>();

        if (arOrders != null) {
            for (ArOrder arOrder : arOrders) {
                QueryWrapper<ArOrderItem> wrapper = new QueryWrapper<ArOrderItem>().eq("order_id", arOrder.getPkId());
                List<ArOrderItem> arOrderItems = arOrderItemMapper.selectList(wrapper);
                // 拼接arOrderItems中的productName
                StringBuilder productNameBuilder = new StringBuilder();
                Set<String> uniqueShopNames = new HashSet<>(); // 使用Set保存唯一的shopName
                Integer totalAmount = 0; // 用于保存amount总和

                for (ArOrderItem arOrderItem : arOrderItems) {
                    productNameBuilder.append(arOrderItem.getProductName()).append(",");

                    QueryWrapper<ArHomeProduct> arHomeProductQueryWrapper = new QueryWrapper<ArHomeProduct>().eq("id", arOrderItem.getProductId());
                    ArHomeProduct arHomeProduct = arHomeProductMapper.selectOne(arHomeProductQueryWrapper);

                    if (arHomeProduct != null) {
                        QueryWrapper<ArHomeShop> arHomeShopQueryWrapper = new QueryWrapper<ArHomeShop>().eq("id", arHomeProduct.getShopId());
                        ArHomeShop arHomeShop = arHomeShopMapper.selectOne(arHomeShopQueryWrapper);

                        if (arHomeShop != null) {
                            uniqueShopNames.add(arHomeShop.getShopName()); // 将shopName添加到Set对象中
                        }
                    }

                    totalAmount += arOrderItem.getAmount(); // 计算amount总和
                }

                String productName = productNameBuilder.length() > 0 ? productNameBuilder.substring(0, productNameBuilder.length() - 1) : "";
                String shopNames = String.join(",", uniqueShopNames); // 使用逗号拼接所有唯一的shopName

                // 创建LatestOrdersVO对象并存入最新的订单列表
                LatestOrdersVO latestOrdersVO = new LatestOrdersVO();
                latestOrdersVO.setOrderNumber(arOrder.getPkId());
                latestOrdersVO.setTotalPrice(arOrder.getTotalPrice());
                latestOrdersVO.setProductName(productName);
                latestOrdersVO.setShopName(shopNames); // 设置shopName
                latestOrdersVO.setAmount(totalAmount); // 设置amount总和
                latestOrdersVO.setOrderStatus(Integer.valueOf(arOrder.getOrderStatus()));
                latestOrdersList.add(latestOrdersVO);
            }
        }

        return latestOrdersList;
    }

    /**
     * 退款订单数量今日本周本月
     *
     * @return
     */
    @Override
    public List<Integer> getRefundOrderNums() {
        List<Integer> refundOrderNums = new ArrayList<>();
        Date date = new Date();
        DateTime beginOfDay = DateUtil.beginOfDay(date);
        DateTime endOfDay = DateUtil.endOfDay(date);
        Integer todayNum = arOrderMapper.selectTimeBetweenRefundOrderNum(beginOfDay, endOfDay);

        DateTime beginOfWeek = DateUtil.beginOfWeek(date);
        DateTime endOfWeek = DateUtil.endOfWeek(date);
        Integer weekNum = arOrderMapper.selectTimeBetweenRefundOrderNum(beginOfWeek, endOfWeek);


        DateTime beginOfMonth = DateUtil.beginOfMonth(date);
        DateTime endOfMonth = DateUtil.endOfMonth(date);
        Integer monthNum = arOrderMapper.selectTimeBetweenRefundOrderNum(beginOfMonth, endOfMonth);

        refundOrderNums.add(todayNum);
        refundOrderNums.add(weekNum);
        refundOrderNums.add(monthNum);
        return refundOrderNums;
    }

    @Override
    public PageData<ArTeam> getTeamList(int current, int size) {
        TeamSearchDTO teamSearchDTO = new TeamSearchDTO();
        teamSearchDTO.setPlatformId("0,100");
        PageHelper.startPage(current, size);
        Page<ArTeam> arTeamPage = arTeamMapper.selectArTeamList(teamSearchDTO);

        Map<Long, Long> teamIdUserCountPairMap = arTeamMapper.countVolunteerCountUnderTeam()
                .stream()
                .collect(Collectors.toMap(TeamIdUserCountPair::getTeamId, TeamIdUserCountPair::getVolunteerCount));
        for (ArTeam arTeam : arTeamPage) {
            arTeam.setVolunteerCount(teamIdUserCountPairMap.get(arTeam.getPkId()));
        }
        return new PageData<>(arTeamPage.getPageNum(), arTeamPage.getPageSize(), arTeamPage.getTotal(), arTeamPage.getResult());
    }

    @Override
    public PageData<ActivityInfoDTO> activityPage(int current, int size) {
        ActivitySearchDTO activitySearchDTO = new ActivitySearchDTO();
        PageHelper.startPage(current, size);
        Page<ArActivity> activityPage = arActivityMapper.selectActivityPageForBigScreen(activitySearchDTO);
        List<ActivityInfoDTO> activityInfoDTOList = ConvertUtil.converList(activityPage.getResult(), ActivityInfoDTO::from);
        return new PageData<>(activityPage.getPageNum(), activityPage.getPageSize(), activityPage.getTotal(), activityInfoDTOList);
    }

    @Override
    public WorkHourPageData<WorkHourItem> workHourDataPage(int current, int size) {
        PageHelper.startPage(current, size);
        Page<WorkHourItem> workHourItems = arActivityMapper.selectWorkHourItemPage();
        WorkHourPageData<WorkHourItem> workHourItemWorkHourPageData = new WorkHourPageData<>(workHourItems.getPageNum(), workHourItems.getPageSize(), workHourItems.getTotal(), workHourItems.getResult());
        Optional<BigDecimal> thisDayTotalWorkHour = arActivityMapper.thisDayTotalWorkHour();
        Optional<BigDecimal> thisWeekTotalWorkHour = arActivityMapper.thisWeekTotalWorkHour();
        Optional<BigDecimal> thisMonthTotalWorkHour = arActivityMapper.thisMonthTotalWorkHour();
        workHourItemWorkHourPageData.setTodayWorkHour(thisDayTotalWorkHour.orElse(BigDecimal.ZERO));
        workHourItemWorkHourPageData.setThisWeekWorkHour(thisWeekTotalWorkHour.orElse(BigDecimal.ZERO));
        workHourItemWorkHourPageData.setThisMonthWorkHour(thisMonthTotalWorkHour.orElse(BigDecimal.ZERO));
        return workHourItemWorkHourPageData;
    }

    @Override
    public PageData<GridVolunteerItem> serviceSiteVolunteer(Long siteId, int current, int size) {
        PageHelper.startPage(current, size);
        Page<GridVolunteerItem> gridVolunteerItems = userMapper.selectServiceSiteVolunteer(siteId);
        return new PageData<>(gridVolunteerItems.getPageNum(), gridVolunteerItems.getPageSize(), gridVolunteerItems.getTotal(), gridVolunteerItems.getResult());
    }

    @Override
    public PageData<GridVolunteerItem> getVolunteerUnderCell(Long gridId, int current, int size) {
        ArRegion arRegion = arRegionMapper.selectArRegionByPkId(gridId);
        String fullRegionId = arRegion.getAncestors() + "," + arRegion.getPkId();
        PageHelper.startPage(current, size);
        Page<GridVolunteerItem> gridVolunteerItems = userMapper.selectUserPageByRegionIdList(fullRegionId);
        return new PageData<>(gridVolunteerItems.getPageNum(), gridVolunteerItems.getPageSize(), gridVolunteerItems.getTotal(), gridVolunteerItems.getResult());
    }
}
